package com.example.micro.aop.login.config;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.example.micro.aop.login.entity.User;
import com.example.micro.aop.login.entity.annotation.Authorized;
import com.example.micro.aop.login.service.UserServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Objects;

@Aspect
@Component
@Slf4j
public class InterceptAspect {
    @Resource
    private UserServiceImpl userService;

    @Pointcut("execution(* com.example.micro.aop.login.controller..*(..))&&@annotation(com.example.micro.aop.login.entity.annotation.Authorized)")
    public void controllerAspect() {
    }

    @Around("controllerAspect()")
    public Object aroundMethod(ProceedingJoinPoint point) {
        HttpServletRequest request;
        Authorized auth = ((MethodSignature) point.getSignature()).getMethod().getAnnotation(Authorized.class);
        if (auth.required()) {
            request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
            String token = request.getHeader("token");
            if (token == null) {
                throw new RuntimeException("无token，请重新登录");
            }
            //获取token的userid
            String userId;
            try {
                List<String> audience = JWT.decode(token).getAudience();
                userId = audience.get(0);
            } catch (JWTDecodeException e) {
                throw new RuntimeException("401");
            }
            User user = userService.getUser(userId);
            if (user == null) {
                throw new RuntimeException("用户不存在");
            }
            //验证token
            JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getPassword())).build();
            try {
                jwtVerifier.verify(token);
            } catch (JWTVerificationException e) {
                throw new RuntimeException("401");
            }
        }
        Object result = null;

        try {
            result = point.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        } finally {

        }
        return result;
    }

}


